package com.goldman.aplt.rule;

import com.goldman.aplt.base.constant.ApConstants;
import com.goldman.aplt.base.type.BaseEnumType;
import com.goldman.aplt.base.type.ComAp;
import com.goldman.aplt.entity.rule.AppRule;
import com.goldman.aplt.entity.rule.AppRuleData;
import com.goldman.aplt.entity.rule.AppRuleInterface;
import com.goldman.aplt.service.rule.AppRuleDataService;
import com.goldman.aplt.service.rule.AppRuleInterfaceService;
import com.goldman.aplt.service.rule.AppRuleService;
import com.goldman.aplt.util.ApBuffer;
import com.goldman.aplt.util.CommUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 文件功能说明： 规则引擎
 * </p>
 *
 * @Author zhuw
 *         <p>
 *         <li>2016年12月12日-上午11:51:55</li>
 *         <li>修改记录</li>
 *         <li>-----------------------------------------------------------</li>
 *         <li>标记：修订内容</li>
 *         <li>20140228 zhuw：创建注释模板</li>
 *         <li>-----------------------------------------------------------</li>
 *         </p>
 */
@Slf4j
@Component
public class ApBaseRule {

    // 参数模板正则表达式
    private static final String paramPattern = "[$]\\{([A-Za-z0-9_\\.]+)\\}";
    // 分割符
    private static final String split = "\\.";

    @Resource
    private AppRuleDataService appRuleDataService;
    @Resource
    private AppRuleInterfaceService appRuleInterfaceService;
    @Resource
    private AppRuleService appRuleService;

    /**
     * @Author zhuw
     *         <p>
     *         <li>2016年12月12日-上午11:56:54</li>
     *         <li>功能说明：判断规则是否成立</li>
     *         <li>如果数据集不是公共运行变量，需要调用addDataToBuffer方法添加数据</li>
     *         <li>1):如果存在例外规则，则一个一个校验，如果有一个成立，则返回false<br/>
     *         2):如果没有例外规则，或者例外规则都不成立，则校验输入的规则，校验成功返回true,失败false<br/>
     *         3):一个规则可以有多个组，一个组可以有多个序号，组之间是'或'的关系，序号之间是'与'的关系<br/>
     *         一个组内所有的序号都true，则该组才为true<br/>
     *         只要有一个组是true，则直接返回true<br/>
     *         </li>
     *         </p>
     * @param ruleId
     *            规则代码
     * @param processor
     *            规则条件匹配结果处理器，如每条规则条件匹配结果详情的记录处理等。
     * @return
     */
    public boolean mapping(String ruleId, ApRuleDataRetProcessor processor) {
        log.info(" ApRule.mapping begin >>>>>>>>>>>>>>>>");
        log.debug("rule id is [%s]", ruleId);

        // 先查看规则代码是否定义
        AppRule ruleInfo = appRuleService.getOneByRuleId(ruleId);

        if (ruleInfo == null) {
            // throw 规则代码[ruleId]没有定义 TODO 错误信息等待定义
//            throw ApPubErr.APPUB.E0005(OdbFactory.getTable(AppRule.class).getLongname(), SysDict.A.rule_id.getLongName(), ruleId);
        }

        BufferedDataVisitor dataVisitor = new BufferedDataVisitor(ruleInfo.getRuleSceneCode());

        // 先判断是否有例外id
        String exceptionRuleId = ruleInfo.getExceptionRuleId();
        if (CommUtil.isNotNull(exceptionRuleId) && checkRule(exceptionRuleId, processor, dataVisitor)) {
            // 例外规则成立，则返回失败
            return false;
        }

        // 检查规则
        boolean isSuccess = checkRule(ruleId, processor, dataVisitor);
        log.debug("mapping result [%s]", isSuccess);
        log.info(" ApRule.mapping end <<<<<<<<<<<<<<<<");

        return isSuccess;
    }

    /**
     * @Author tsichang
     *         <p>
     *         <li>2018年2月8日-下午3:27:19</li>
     *         <li>修改记录</li>
     *         <li>-----------------------------------------------------------</li>
     *         <li>标记：修订内容</li>
     *         <li>2018年2月8日-tsichang：规则条件的匹配结果处理</li>
     *         <li>-----------------------------------------------------------</li>
     *         </p>
     */
    public interface ApRuleDataRetProcessor {
        void process(ComAp.ApRuleMappingDetail mappingDetail);
    }

    public boolean mapping(String ruleId) {
        return mapping(ruleId, log.isDebugEnabled() ? DefaultRuleDataRetProcessor.getInstance() : null);
    }

    /**
     * @Author zhuw
     *         <p>
     *         <li>2016年12月12日-下午1:09:36</li>
     *         <li>功能说明：按规则场景代码扫描并返回首个命中回执，无命中返回null</li>
     *         </p>
     * @return
     */
    public String getFirstResultByScene(String sceneCode) {
        return getFirstResultByScene(sceneCode, log.isDebugEnabled() ? DefaultRuleDataRetProcessor.getInstance() : null);
    }

    public String getFirstResultByScene(String sceneCode, ApRuleDataRetProcessor processor) {
        List<String> rule = getAllResult(sceneCode, processor, true);
        return (!rule.isEmpty()) ? rule.get(0) : null;
    }

    /**
     * @Author zhuw
     *         <p>
     *         <li>2016年12月12日-下午1:10:38</li>
     *         <li>功能说明：按规则场景类型扫描并返回全部命中回执，无命中返回空列表</li>
     *         </p>
     * @return
     */
    public List<String> getAllResultByScene(String sceneCode) {
        return getAllResultByScene(sceneCode, log.isDebugEnabled() ? DefaultRuleDataRetProcessor.getInstance() : null);
    }

    public List<String> getAllResultByScene(String sceneCode, ApRuleDataRetProcessor processor) {
        return getAllResult(sceneCode, processor, false);
    }

//    /**
//     * @Author shenxy
//     *         <p>
//     *         <li>2017年9月22日-下午3:50:02</li>
//     *         <li>功能说明：交易控制检查</li>
//     *         </p>
//     * @param eventId
//     *            交易事件ID
//     */
//    public void checkTrxnControl(String eventId) {
//
//        checkError(eventId);
//
//        checkWarning(eventId);
//
//        checkSceneAuthor(eventId);
//    }
//
//    /**
//     * 场景授权检查
//     */
//    private void checkSceneAuthor(String eventId) {
//        log.info(" ApRule.checkSceneAuthor begin >>>>>>>>>>>>>>>>");
//
//        // 获取公共运行区
//        RunEnvs runEnvs = BizUtil.getTrxRunEnvs();
//
//        if (runEnvs.getAuth_ind() == E_YESORNO.YES)
//            return;
//
//        // 查询数据
//        List<app_trxn_control> trxnCtrlList = App_trxn_controlDao.selectAll_odb3(eventId, E_TRXNCTRLTYPE.SCENE_AUTHOR, false);
//
//        Options<AuthReason> listReason = runEnvs.getAuth_reason();
//
//        // 不为空进行交易控制检查
//        for (app_trxn_control trxnCtrl : trxnCtrlList) {
//
//            if (mapping(trxnCtrl.getTrxn_ctrl_run_cond())) {
//
//                // 判断场景授权码是否存在
//                ApBaseDropList.exists(ApConst.SCENE_AUTH_ID, trxnCtrl.getScene_auth_id(), true);
//
//                // 实例化授权原因
//                AuthReason authReason = BizUtil.getInstance(AuthReason.class);
//
//                authReason.setAuth_reason_type(E_AUTHREASONTYPE.SENCE);
//                authReason.setAuth_reason_id(trxnCtrl.getScene_auth_id());
//                authReason.setAuth_reason_desc(getHintText(trxnCtrl));
//
//                // 添加角色id
//                List<app_scene_auth> sceneAuthList = App_scene_authDao.selectAll_odb2(trxnCtrl.getScene_auth_id(), false);
//
//                String temp = "";
//                for (app_scene_auth sceneAuth : sceneAuthList) {
//                    temp = temp.concat(sceneAuth.getRole_id()).concat(",");
//                }
//
//                authReason.setAuth_role_list(temp);
//
//                listReason.add(authReason);
//            }
//        }
//
//        runEnvs.setAuth_reason(listReason);
//
//        log.info(" ApRule.checkSceneAuthor end <<<<<<<<<<<<<<<<");
//
//    }

//    /**
//     * 检查并收集错误，中断交易返回给调用方
//     */
//    private void checkWarning(String eventId) {
//        log.info(" ApRule.checkWarning begin >>>>>>>>>>>>>>>>");
//
//        // 获取公共运行区
//        RunEnvs runEnvs = BizUtil.getTrxRunEnvs();
//
//        if (runEnvs.getWarning_confirm_ind() == E_YESORNO.YES)
//            return;
//
//        // 获取交易控制数据
//        List<app_trxn_control> trxnCtrlList = App_trxn_controlDao.selectAll_odb3(eventId, E_TRXNCTRLTYPE.WARNING, false);
//
//        // 不为空进行交易控制检查
//        for (app_trxn_control trxnCtrl : trxnCtrlList) {
//
//            // AppRule做判断，为空或判断成功抛出异常
//            if (mapping(trxnCtrl.getTrxn_ctrl_run_cond())) {
//
//                // 获得提示文本
//                String hintText = getHintText(trxnCtrl);
//
//                // 判断是否有相同客户号的数据
//                for (WarningInfo warningInfo : runEnvs.getWarning_info()) {
//
//                    if (CommUtil.equals(warningInfo.getShow_error_info(), hintText))
//
//                        return;
//                }
//
//                // 初始化警告信息
//                WarningInfo warningInfo = BizUtil.getInstance(WarningInfo.class);
//
//                warningInfo.setTrxn_event_id(trxnCtrl.getTrxn_event_id());// 交易事件id
//
//                warningInfo.setTrxn_ctrl_desc(trxnCtrl.getTrxn_ctrl_desc());// 交易控制描述
//
//                warningInfo.setShow_error_info(hintText);// 错误异常展示信息
//
//                runEnvs.getWarning_info().add(warningInfo);
//
//            }
//
//        }
//
//        log.info(" ApRule.checkWarning end <<<<<<<<<<<<<<<<");
//    }
//
//    /**
//     * 获得提示文本
//     */
//    private String getHintText(app_trxn_control trxnCtrl) {
//        log.info(" ApRule.getHintText begin >>>>>>>>>>>>>>>>");
//
//        String hintText = null;
//
//        // 优先去数据集取值
//
//        if (CommUtil.isNotNull(trxnCtrl.getHint_data_mart()) && CommUtil.isNotNull(trxnCtrl.getHint_field_name())) {
//
//            try {
//
//                hintText = ApBaseBuffer.getFieldValue(trxnCtrl.getHint_data_mart(), trxnCtrl.getHint_field_name());
//            }
//            catch (AdpBusinessException e) {
//                log.info("errorCode:[%s],errorMessage:[%s]", e, e.getCode(), e.getMessage());
//
//            }
//
//        }
//
//        if (CommUtil.isNull(hintText)) {
//
//            hintText = trxnCtrl.getHint_text();
//        }
//
//        // 获得处理后的文本
//        String text = paramTemplate(ApBuffer.getBuffer(), hintText, null);
//
//        log.info(" ApRule.getHintText end <<<<<<<<<<<<<<<<");
//
//        return text;
//    }
//
//    /**
//     * 检查若遇到一个立即抛出异常
//     */
//    private void checkError(String eventId) {
//        log.info(" ApRule.checkError begin >>>>>>>>>>>>>>>>");
//
//        // 获取交易控制数据
//        List<app_trxn_control> trxnCtrlList = App_trxn_controlDao.selectAll_odb3(eventId, E_TRXNCTRLTYPE.ERROR, false);
//
//        // 不为空进行交易控制检查
//        for (app_trxn_control trxnCtrl : trxnCtrlList) {
//
//            // AppRule做判断，为空或判断成功抛出异常
//            if (mapping(trxnCtrl.getTrxn_ctrl_run_cond())) {
//
//                String hintText = getHintText(trxnCtrl);
//
//                if (CommUtil.isNotNull(trxnCtrl.getReturn_code())) {
//                    throw new AdpBusinessException(ErrorType.ERROR, trxnCtrl.getReturn_code(), hintText);
//                }
//                else {
//                    throw ApBaseErr.ApBase.E0068(hintText);
//                }
//            }
//
//        }
//
//        log.info(" ApRule.checkError end <<<<<<<<<<<<<<<<");
//
//    }
//
//    /**
//     * @Author shenxy
//     *         <p>
//     *         <li>2017年9月29日-下午2:27:47</li>
//     *         <li>功能说明：弹出告警</li>
//     *         </p>
//     */
//    public void popupWarning() {
//
//        RunEnvs runEnvs = BizUtil.getTrxRunEnvs();
//
//        if (runEnvs.getWarning_confirm_ind() == E_YESORNO.YES)
//            return;
//
//        if (!runEnvs.getWarning_info().isEmpty()) {
//
//            throw ApBaseErr.ApBase.E0059();
//        }
//    }
//
//    /**
//     * @Author shenxy
//     *         <p>
//     *         <li>2017年10月26日-上午9:45:41</li>
//     *         <li>功能说明：弹出场景授权窗口</li>
//     *         </p>
//     */
//    public void popupSceneAuth() {
//        log.info(" ApRule.popupSceneAuth begin >>>>>>>>>>>>>>>>");
//
//        RunEnvs runEnvs = BizUtil.getTrxRunEnvs();
//
//        if (runEnvs.getAuth_ind() == E_YESORNO.YES)
//            return;
//
//        Options<AuthReason> authReasonList = runEnvs.getAuth_reason();
//        if (!authReasonList.isEmpty()) {
//
//            for (AuthReason authReason : authReasonList) {
//                if (CommUtil.isNull(authReason.getAuth_role_list())) {
//
//                    throw ApBaseErr.ApBase.E0063();
//                }
//            }
//            /**
//             * 授权检查，需要授权则此交易回滚 xiang 2019年9月24日
//             */
//            DBUtil.rollBack();
//            throw ApBaseErr.ApBase.E0062();
//        }
//
//        log.info(" ApRule.popupSceneAuth end <<<<<<<<<<<<<<<<");
//    }

    /**
     * 通用获取result
     *
     * @param sceneCode
     *            场景代码
     * @param firstFlag
     *            是否只获取第一行数据
     */
    private List<String> getAllResult(String sceneCode, ApRuleDataRetProcessor processor, boolean firstFlag) {
        List<String> rulesResult = new ArrayList<String>();// 规则代码结果集

        List<AppRule> rulesList = appRuleService.getListByScene(sceneCode);
        CommUtil.listSort(rulesList, true, "mappingSort");

        for (AppRule rules : rulesList) {
            if (CommUtil.compare(rules.getEffectDate(), CommUtil.getTrxnEnvs().getTrxn_date()) > 0
                    || CommUtil.compare(rules.getExpiryDate(), CommUtil.getTrxnEnvs().getTrxn_date()) < 0) {
                log.debug("Rule[%s] of scene[%s] is not effective.", rules.getRuleId(), sceneCode);
                continue;
            }

            if (mapping(rules.getRuleId(), processor)) {
                rulesResult.add(rules.getMappingResult());
            }
            else {
                continue;
            }

            if (firstFlag)
                break;
        }

        return rulesResult;
    }

    /**
     * 内部校验单个规则id,不含例外的控制
     */
    public boolean checkRule(String ruleId, ApRuleDataRetProcessor processor, BufferedDataVisitor dataVisitor) {
        // 规则数据定义，数据已按组和序号排序
        List<AppRuleData> ruleData = appRuleDataService.getListByRuleId(ruleId);
        log.debug("rule data size of rule[%s] is %s", ruleId, ruleData.size());

        CommUtil.listSort(ruleData, true, "ruleGroupNo", "ruleSort");

        // Map<String, Object> ruleBuffer = ApBuffer.getBuffer();// 规则缓冲区
        String groupId = "";// 初始组
        boolean isSuccess = true;
        for (AppRuleData rule : ruleData) {
            String tmpGroupId = String.valueOf(rule.getRuleGroupNo());
            if ("".equals(groupId)) {
                groupId = tmpGroupId;
            }
            else {
                if (!groupId.equals(tmpGroupId) && isSuccess)// 如果不是同一个组，但是上个组成功，则跳出
                    break;

                if (groupId.equals(tmpGroupId) && !isSuccess)// 如果是同一个组，但是组内已经有一个校验失败，则跳过
                    continue;

                if (!groupId.equals(tmpGroupId))// 如果不是同一个组，但是上个组失败，则继续
                    groupId = tmpGroupId;
            }

            log.debug("group id [%s]  rule sort [%s]", groupId, rule.getRuleSort());
            isSuccess = checkRuleSingle(rule, processor, dataVisitor);
        }

        return isSuccess;
    }

    /**
     * 单条记录的检查
     *
     * @param processor
     */
    private boolean checkRuleSingle(AppRuleData rule, ApRuleDataRetProcessor processor, BufferedDataVisitor dataVisitor) {
        // String dataMart = rule.getData_mart();

        Object value;
        if (rule.getRuleExprType().equals(BaseEnumType.E_RULEEXPTYPE.COMMON.getValue())) {
            value = dataVisitor.getFieldValue(rule.getFieldName());
        }
        else {
            //TODO 暂时不支持函数计算的规则
//            value = ApRuleFunc.eval(rule, dataVisitor);
            value = null;
        }

        Object mappingValue = paramTemplate(rule.getDataMappingValue(), dataVisitor);
        //scc xuqiu,zhe ge rule bu qu fen da xiao xie
        if(rule.getRuleId().equals("SENSITIVE_WORD_CTRL_001")) {
            if(CommUtil.isNotNull(value)) {
                value = value.toString().toLowerCase();
            }
            if(CommUtil.isNotNull(mappingValue)) {
                mappingValue = mappingValue.toString().toLowerCase();
            }
        }
        return check(value, mappingValue, rule, processor);
    }

    /**
     * <p>
     * <li>2018年2月26日-上午10:50:57</li>
     * <li>功能说明： 参数按照模板替换 ${column_name}</li>
     * </p>
     *
     * @param value
     * @param dataVisitor
     * @return
     */
    protected String paramTemplate(String value, BufferedDataVisitor dataVisitor) {
        if (value == null || value.length() == 0)
            return value;

        Pattern pat = Pattern.compile(paramPattern);
        Matcher mather = pat.matcher(value);

        String ret = value;
        StringBuilder sb = new StringBuilder(value);

        int offset = 0;

        while (mather.find()) {
            String[] keys = mather.group(1).split(split);

            String v;
            if (keys.length > 1) {
                v = dataVisitor.getFieldValue(keys[0], keys[1]).toString();
            }
            else {
                v = dataVisitor.getFieldValue(keys[0]).toString();
            }

            ret = sb.replace(mather.start() - offset, mather.end() - offset, v).toString();

            offset = mather.group().length() - v.length() + offset;
        }

        return ret;
    }

    /**
     * 参数按照模板替换 ${RUN_ENV.trx_date}、${INPUT.acct_no}或 ${trx_date}取默认的dataMart
     *
     * @param ruleBuffer
     * @return
     */
    public String paramTemplate(Map<String, Object> ruleBuffer, String value, String defaultDataMart) {
        if (value == null || value.length() == 0)
            return value;

        Pattern pat = Pattern.compile(paramPattern);
        Matcher mather = pat.matcher(value);

        String ret = value;
        StringBuilder sb = new StringBuilder(value);

        int offset = 0;

        while (mather.find()) {
            String[] keys = mather.group(1).split(split);
            String dataMart = keys.length > 1 ? keys[0] : defaultDataMart;
            String key = keys.length > 1 ? keys[1] : keys[0];

            String v = getValueByBuffer(ruleBuffer, dataMart, key).toString();

            ret = sb.replace(mather.start() - offset, mather.end() - offset, v).toString();

            offset = mather.group().length() - v.length() + offset;
        }

        return ret;
    }

    /*
     * 从buffer区取值
     */
    private Object getValueByBuffer(Map<String, Object> ruleBuffer, String dataMart, String key) {
        return getValueByBuffer(ruleBuffer, dataMart, key, false);
    }

    private Object getValueByBuffer(Map<String, Object> ruleBuffer, String dataMart, String key, boolean nullable) {
        Object ret = null;

        if (ApConstants.RUN_ENVS.equals(dataMart)) {
            ret = CommUtil.getTrxRunEnvsValue(key);
        }
        else {
            Object dataObj = ruleBuffer.get(dataMart);// 数据集
            if (dataObj != null && dataObj instanceof Map) {
                Map<String, Object> data = (Map<String, Object>) dataObj;
                ret = data.get(key);
            }
        }

        return ret == null ? (nullable ? null : "") : ret;
    }

    /**
     * 校验控制
     *
     * @param processor
     */
    private boolean check(Object value, Object mappingValue, AppRuleData rule, ApRuleDataRetProcessor processor) {
        Logic logicOperator = Logic.getLogicOperator(rule.getDataMappingOperator());
        boolean isSuccess = logicOperator.check(value, mappingValue);

        if (CommUtil.isNotNull(processor)) {
            ComAp.ApRuleMappingDetail mappingDetail = new ComAp.ApRuleMappingDetail();
            mappingDetail.setRuleId(rule.getRuleId()); // rule id
            mappingDetail.setRuleGroupNo(rule.getRuleGroupNo()); // rule
            // group
            // no
            mappingDetail.setRuleSort(rule.getRuleSort()); // rule sort
            mappingDetail.setDataMappingOperator(rule.getDataMappingOperator()); // data
            // mapping
            // operator
            mappingDetail.setCheckingValue(value == null ? "" : value.toString());
            mappingDetail.setDataMappingValue(mappingValue == null ? "" : mappingValue.toString());
            mappingDetail.setSuccMappingFlag(isSuccess ? BaseEnumType.E_YESORNO.YES : BaseEnumType.E_YESORNO.NO);
            mappingDetail.setFieldName(rule.getRuleExprType().equals(BaseEnumType.E_RULEEXPTYPE.COMMON.getValue()) ? rule.getFieldName() : rule.getFuncCode());

            processor.process(mappingDetail);
        }

        return isSuccess;
    }

    private static enum Logic {
        EQUAL {
            @Override
            protected boolean check(Object value, Object mappingValue) {
                if (value == null || mappingValue == null) {
                    return value == null && mappingValue == null;
                }
                else {
                    return _check(value, mappingValue);
                }
            }

            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkEq(value, mappingValue);
            }

        },
        NO_EQUAL {
            boolean check(Object value, Object mappingValue) {
                if (value == null || mappingValue == null) {
                    return !(value == null && mappingValue == null);
                }
                else {
                    return _check(value, mappingValue);
                }
            }

            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkNe(value, mappingValue);
            }

        },
        IN {
            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkIn(value, mappingValue);
            }
        },
        NO_IN {
            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkNi(value, mappingValue);
            }
        },
        GREATER_THAN {
            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkGt(value, mappingValue);
            }
        },
        LESS_THAN {
            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkLt(value, mappingValue);
            }
        },
        GREATER_THAN_OR_EQUAL {
            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkGteq(value, mappingValue);
            }
        },
        LESS_THAN_OR_EQUAL {
            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkLteq(value, mappingValue);
            }
        },
        REQULAR_EXPRESSION {
            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkExp(value, mappingValue);
            }
        },
        CONTAIN {
            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkContain(value, mappingValue);
            }
        },
        NOT_CONTAIN {
            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return checkNotContain(value, mappingValue);
            }
        },
        NONE { // default empty logic
            @Override
            protected boolean _check(Object value, Object mappingValue) {
                return false;
            }
        };

        protected abstract boolean _check(Object value, Object mappingValue);

        boolean check(Object value, Object mappingValue) {
            if (value == null || mappingValue == null) {
                return false;
            }
            else {
                return _check(value, mappingValue);
            }
        }

        static Logic getLogicOperator(BaseEnumType.E_OPERATOR orgOperator) {
            try {
                return Logic.valueOf(orgOperator.getId());
            }
            catch (Exception e) {
                return Logic.NONE;
            }
        }
    }

    /**
     * equal校验方法
     */
    private static boolean checkEq(Object value, Object mappingValue) {
        BigDecimal v, mapV;
        try {
            v = new BigDecimal(value.toString());
            mapV = new BigDecimal(mappingValue.toString());
        }
        catch (NumberFormatException e) {// 如果其中有一个不能转成bigDecimal，则判断对应的字符串
            return (CommUtil.compare(value.toString(), mappingValue.toString()) == 0) ? true : false;
        }

        return (CommUtil.compare(v, mapV) == 0) ? true : false;
    }

    /**
     * not equal校验
     */
    private static boolean checkNe(Object value, Object mappingValue) {
        return checkEq(value, mappingValue) ? false : true;
    }

    /**
     * in校验
     */
    private static boolean checkIn(Object value, Object mappingValue) {
        if ("".equals(value.toString())) // in校验，如果是空字符串，直接返回失败
            return false;

        int i = mappingValue.toString().indexOf(value.toString());
        return (i != -1) ? true : false;
    }

    /**
     * not in校验
     */
    private static boolean checkNi(Object value, Object mappingValue) {
        return checkIn(value, mappingValue) ? false : true;
    }

    /**
     * greater-than校验
     */
    private static boolean checkGt(Object value, Object mappingValue) {
        Object newValue = "".equals(value.toString()) ? 0 : value; // 初始化0处理

        BigDecimal v, mapV;
        try {
            v = new BigDecimal(newValue.toString());
            mapV = new BigDecimal(mappingValue.toString());
        }
        catch (NumberFormatException e) {
            return false;// 转换错误，返回false
        }
        return (CommUtil.compare(v, mapV) == 1) ? true : false;
    }

    /**
     * less-than校验
     */
    private static boolean checkLt(Object value, Object mappingValue) {
        Object newValue = "".equals(value.toString()) ? 0 : value; // 初始化0处理

        BigDecimal v, mapV;
        try {
            v = new BigDecimal(newValue.toString());
            mapV = new BigDecimal(mappingValue.toString());
        }
        catch (NumberFormatException e) {
            return false;// 转换错误，返回false
        }
        return (CommUtil.compare(v, mapV) == -1) ? true : false;
    }

    /**
     * less-than校验
     */
    private static boolean checkGteq(Object value, Object mappingValue) {
        return checkLt(value, mappingValue) ? false : true;
    }

    /**
     * less-then or equal校验
     */
    private static boolean checkLteq(Object value, Object mappingValue) {
        return checkGt(value, mappingValue) ? false : true;
    }

    /**
     * regular-expression校验
     */
    private static boolean checkExp(Object value, Object mappingValue) {
        return value.toString().matches(mappingValue.toString());
    }

    /**
     *
     */
    private static boolean checkContain(Object value, Object mappingValue) {
        return checkIn(mappingValue, value);
    }

    /**
     *
     */
    private static boolean checkNotContain(Object value, Object mappingValue) {
        return !checkContain(value, mappingValue);
    }

    private static class DefaultRuleDataRetProcessor implements ApRuleDataRetProcessor {
        private static final DefaultRuleDataRetProcessor inst = new DefaultRuleDataRetProcessor();

        public static ApRuleDataRetProcessor getInstance() {
            return inst;
        }

        @Override
        public void process(ComAp.ApRuleMappingDetail mappingDetail) {
            log.debug("check operator is [%s]", mappingDetail.getDataMappingOperator());
            log.debug("check value    is [%s]", mappingDetail.getCheckingValue());
            log.debug("mappingValue   is [%s]", mappingDetail.getDataMappingValue());
            log.debug("check result   is [%s]", mappingDetail.getSuccMappingFlag());
        }
    }

    public class BufferedDataVisitor {
        private String ruleScene;

        protected BufferedDataVisitor(String ruleScene) {
            this.ruleScene = ruleScene;
        }

        protected Object getFieldValue(String columnName) {
            return getFieldValue(columnName, false);
        }

        protected Object getFieldValue(String dataMart, String columnName) {
            return getFieldValue(dataMart, columnName, false);
        }

        protected Object getFieldValue(String dataMart, String columnName, boolean nullable) {
            return getValueByBuffer(ApBuffer.getBuffer(), dataMart, columnName, nullable);
        }

        protected Object getFieldValue(String columnName, boolean nullable) {
            AppRuleInterface ruleFace = appRuleInterfaceService.getOne(ruleScene, columnName);

            if (ruleFace == null) {
                ruleFace = appRuleInterfaceService.getOne(ApConstants.WILDCARD, columnName);
            }

            if (ruleFace == null) {
                //TODO 待定义错误
//                throw ApPubErr.APPUB.E0024(OdbFactory.getTable(AppRule_interface.class).getLongname(), SysDict.A.rule_scene_code.getLongName(), ruleScene,
//                        SysDict.A.field_name.getLongName(), columnName);
            }

            return getValueByBuffer(ApBuffer.getBuffer(), ruleFace.getDataMart(), ruleFace.getColumnName(), nullable);
        }

    }

    /**
     * 判断规则ID是否存在
     *
     * @param ruleId
     *            规则ID
     * @return true-存在 false-不存在
     */
    public boolean existsRule(String ruleId) {

        AppRule ruleInfo = appRuleService.getOneByRuleId(ruleId);

        return ruleInfo == null ? false : true;
    }


    /**
     * 获取规则信息
     *
     * @param ruleId
     *            规则ID
     * @param errFlag
     *            是否报错标志
     * @return 规则信息
     */
    public AppRule getRuleIInfo(String ruleId, boolean errFlag) {

        AppRule ruleInfo = appRuleService.getOneByRuleId(ruleId);

        if (ruleInfo == null && errFlag) {
            //TODO 需要抛错
            //throw ApPubErr.APPUB.E0005(OdbFactory.getTable(AppRule.class).getLongname(), SysDict.A.rule_id.getLongName(), ruleId);
        }

        return ruleInfo;
    }

}
